package satir.card;

import java.util.ArrayList;
import java.util.Scanner;
import satir.command.AskQuestionCmd;
import satir.framework.InputValidator;
import satir.player.Player;
import satir.record.Recordable;

/**
 * The Class AwardSECard. This class generalize the type of card that would
 * reward self esteem to player
 * @version 3.0 April 2012
 * @author Creative Family
 */
public abstract class ActionCard extends Card implements Recordable {

    /** The questions. */
    protected ArrayList<Question> questions;

    /** The record. */
    protected ArrayList<AskQuestionCmd> record;

    /** The is ignore record. */
    private boolean isIgnoreRecord;

    /**
     * Instantiates a new award SE card.
     * @param key
     *            the key
     * @param name
     *            the name
     * @param questions
     *            the questions
     */
    public ActionCard(final String key, final String name, final ArrayList<Question> questions) {
	super(key, name);
	this.questions = questions;
	record = new ArrayList<AskQuestionCmd>();
	isIgnoreRecord = false;
    }

    /**
     * Gets the questions.
     * @return the questions
     */
    public ArrayList<Question> getQuestions() {
	return questions;
    }

    /**
     * Activates the card.
      * @param player
     *         the Player object
     */
    protected abstract void doActivateCard(Player player);

    /**
     * Use magic tool.
     * @param player
     *            the player
     * @param cardType
     *            the card type
     * @return true if player is going to use magic tool
     */
    protected boolean useMagicTool(final Player player, final String cardType) {
	int toolIndex = 0;
	boolean isUseTool = false;
	boolean hasUsableTool = false;
	ArrayList<MagicToolCard> mtCards = player.getMtCards();
	ArrayList<MagicToolCard> usableCards = new ArrayList<MagicToolCard>();

	// Check if the player has usable magic tool
	hasUsableTool = hasUsableMagic(mtCards, usableCards, cardType);
	if (hasUsableTool) { // player has usable tool
		System.out.println(name);
		System.out.println(questions.get(0).getQuestion());
		System.out.println("");
	    isUseTool = askIsUseTool();
	    if (isUseTool) {
		toolIndex = getMagicToolChoice(usableCards);
		MagicToolCard useMTCard = usableCards.get(toolIndex - 1);
		useMTCard.activateCard(player);
		player.removeMtCard(useMTCard);
	    }
	}else{
	    isUseTool = false;
	}
	isIgnoreRecord = isUseTool;
	return isUseTool;
    }

    /**
     * Checks for usable magic.
     * @param mtCards the magic tool cards
     * @param usableCards the usable cards
     * @param cardType the card type
     * @return true, if successful
     */
    private boolean hasUsableMagic(final ArrayList<MagicToolCard> mtCards,
	    final ArrayList<MagicToolCard> usableCards, final String cardType) {
	boolean hasUsableTool = false;
	for (int i = 0; i < mtCards.size(); i++) {
	    MagicToolCard mtCardTmp = mtCards.get(i);
	    if ((mtCardTmp.getTargetCard().equals(cardType))
		    || (mtCardTmp.getTargetCard().equals("Any"))) {
		usableCards.add(mtCardTmp);
		hasUsableTool = true;
	    }
	}
	return hasUsableTool;
    }

    /**
     * Ask is use tool.
     * @return true if player chooses to use magic tool, otherwise false
     */
    private boolean askIsUseTool() {
	Scanner sc = new Scanner(System.in);
	boolean isInValidInput = false;
	String userInput;
	int choiceIndex = 0;
	boolean isUseTool;
	do {
	    System.out
		    .println("Would you like to use Magic Tools? ([1]Yes or [2]No)");
	    userInput = sc.next();
	    isInValidInput = InputValidator.isInteger(userInput);
	    if (isInValidInput) {
		choiceIndex = Integer.parseInt(userInput);
		isInValidInput = !InputValidator.isWithinRange(choiceIndex, 1, 2);
		if (isInValidInput) {
		    System.out.println("Out of Range!");
		}
	    } else {
		System.out.println("Please input 1 or 2");
		isInValidInput = true;
	    }
	} while (isInValidInput);
	isUseTool = (choiceIndex == 1);
	return isUseTool;
    }

    /**
     * Gets the magic tool choice.
     * @param usableCards the usable cards
     * @return the magic tool choice
     */
    private int getMagicToolChoice(final ArrayList<MagicToolCard> usableCards) {
	Scanner sc = new Scanner(System.in);
	String userInput;
	boolean isInValidInput = false;
	int toolIndex = 0;
	do {
	    System.out.println("Use which Magic Tools?");
	    for (int i = 0; i < usableCards.size(); i++) {
		MagicToolCard mtCardTmp = usableCards.get(i);
		System.out.println((i + 1) + ". " + mtCardTmp.getName());
	    }
	    userInput = sc.next();
	    isInValidInput = InputValidator.isInteger(userInput);
	    if (isInValidInput) {
		toolIndex = Integer.parseInt(userInput);
		isInValidInput = !InputValidator.isWithinRange(toolIndex,
			1, usableCards.size());
		if (isInValidInput) {
		    System.out.println("Out of Range!");
		}
	    } else {
		System.out.println("Please input a number");
		isInValidInput = true;
	    }
	} while (isInValidInput);
	return toolIndex;
    }

    /**
     * Gets the status of record.
     * @return status of record, true if ignore record, otherwise false.
     */
    public boolean getIsIgnoreRecord() {
	return isIgnoreRecord;
    }

    /**
     * Checks if is number.
     *
     * @param input the input
     * @return true, if is number
     */
    private boolean isNumber(final String input) {
	try {
	    Integer.parseInt(input);
	    return true;
	} catch (NumberFormatException e) {
	    return false;
	}
    }
}
